package oop.core.entity;

import java.util.List;

import oop.core.item.Equipment;
import oop.core.item.Inventory;
import oop.core.item.Item;
import oop.core.item.TakeableItem;
import oop.core.map.Location;
import oop.core.map.MovementType;
import oop.core.view.Renderable;

/**
 * 
 */

public abstract class Entity implements Renderable {
	protected String imageID;
	protected String name;
	protected int direction;
	protected Location loc;
	protected boolean isVisible;
	protected Equipment equipment;
	protected Inventory inventory;
	protected List<MovementType> movementTypes;
	protected DerivedStats derStats;
	protected int givenEXP;
	protected boolean delayFlag = false;
	
	protected Entity(String imageID, String name, int direction, Location loc, boolean isVisible, Equipment equipment, Inventory inventory, List<MovementType> movementType, DerivedStats derivedStats, int givenEXP){
		this.imageID = imageID;
		this.name = name;
		this.direction = direction;
		this.loc = loc;
		this.isVisible = isVisible;
		this.equipment = equipment;
		this.inventory = inventory;
		this.movementTypes = movementType;
		this.derStats = derivedStats;
	}
	
	/**
	 * Increases the entity's exp.
	 * @param exp
	 */
	public void giveEXP(int exp)
	{
		derStats.giveEXP(exp);
	}
	
	public int getHP()
	{
		return derStats.getHP();
	}
	
	public void attackEntity(Entity e){
		e.takeDamage(this.derStats.calcDamage(0));
	}
	
	public void takePiercingDamage(int dam){
		derStats.takePiercingDamage(dam);
	}
	
	public void takeDamage(int dam){
		derStats.takeDamage(dam);
	}
	
	public void lowerMP(int mana)
	{
		derStats.lowerMP(mana);
	}
	
	public void takeLives(int lives){
		die();
	}
	
	public void heal(int health){
		derStats.heal(health);
	}
	
	public void setLocation(Location l){
		loc.setLocation(l.getXPos(), l.getYPos());
	}
	
	public void doLevelUp(int levels){
		
	}
	
	public void die()
	{
		loc = null;
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((name == null) ? 0 : name.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Entity other = (Entity) obj;
		if (name == null) {
			if (other.name != null)
				return false;
		} else if (!name.equals(other.name))
			return false;
		return true;
	}

	public String getName() {
		return name;
	}
	
	public int getGivenEXP() {
		return givenEXP;
	}

	public void setGivenEXP(int givenEXP) {
		this.givenEXP = givenEXP;
	}
	
	public int getXLoc(){
		return loc.getXPos();
	}
	
	public int getYLoc(){
		return loc.getYPos();
	}
	
	public void setName(String name) {
		this.name = name;
	}

	public int getDirection() {
		return direction;
	}

	public void setDirection(int direction) {
		this.direction = direction;
	}

	public Location getLoc() {
		return loc;
	}

	public void setLoc(Location newLoc) {
		this.loc = newLoc;
	}

	public boolean isVisible() {
		return isVisible;
	}

	public void setVisible(boolean isVisible) {
		this.isVisible = isVisible;
	}

	public Equipment getEquipment() {
		return equipment;
	}

	public void setEquipment(Equipment equipment) {
		this.equipment = equipment;
	}

	public Inventory getInventory() {
		return inventory;
	}

	public void setInventory(Inventory inventory) {
		this.inventory = inventory;
	}

	public List<MovementType> getMovementTypes() {
		return movementTypes;
	}

	public void setMovementTypes(List<MovementType> movementTypes) {
		this.movementTypes = movementTypes;
	}

	public DerivedStats getDerStats() {
		return derStats;
	}

	public void setDerStats(DerivedStats derStats) {
		this.derStats = derStats;
	}

	public void setDelayFlag()
	{
		delayFlag = true;
	}
	
	public void clearDelayFlag()
	{
		delayFlag = false;
	}
	
	public boolean getDelayFlag()
	{
		return delayFlag;
	}
	
	public void addToInventory(TakeableItem i)
	{
		this.inventory.addItem(i);
	}
	
	public String getImageID()
	{
		return imageID + direction;
	}
}

